package com.voe;

import com.voe.callback.VoETelephoneEventObserver;
import com.voe.common.OutputParam;
import com.voe.common.ReturnValue;
import com.voe.common.TelephoneEventDetectionMethods;
import com.voe.common.Utility;

/**This sub-API supports the following functionalities:<br/>
*<br/>
*- Telephone event transmission.<br/>
*- DTMF tone generation.<br/>
*<br/>
*Usage example, omitting error checking:<br/>
*<br/>
*VoiceEngine voe = VoiceEngine.createInterface();<br/>
*VoEBase base = VoEBase.createInterface(voe);<br/>
*VoEDtmf dtmf  = VoEDtmf.createInterface(voe);<br/>
*base.init();<br/>
*int ch = base.createChannel();<br/>
*...<br/>
*dtmf.sendTelephoneEvent(ch, 7);<br/>
*...<br/>
*base.deleteChannel(ch);<br/>
*base.terminate();<br/>
*base.release();<br/>
*dtmf.release();<br/>
*voe.release();<br/>
*/
public class VoEDtmf {

	// [start] apis
	
	public static VoEDtmf createInstance(VoiceEngine voiceEngine) {

		long p = GetInterface(voiceEngine._p);
		if(p != 0)
			return new VoEDtmf(p);
		return null;
	}

	public void release() {
		if (_p != 0) {
			Release(_p);
		}
	}

	/** Sends telephone events either in-band or out-of-band.
	 */
	public int sendTelephoneEvent(int channel,
			int eventCode, boolean outOfBand, int lengthMs, int attenuationDb) {
		return SendTelephoneEvent(_p, channel, eventCode, outOfBand, lengthMs, attenuationDb);
	}

	/** Sends telephone events either in-band or out-of-band.
	 */
	public int sendTelephoneEvent(int channel,
			int eventCode, boolean outOfBand, int lengthMs) {
		return sendTelephoneEvent(channel, eventCode, outOfBand, lengthMs, 10);
	}

	/** Sends telephone events either in-band or out-of-band.
	 */
	public int sendTelephoneEvent(int channel,
			int eventCode, boolean outOfBand) {
		return sendTelephoneEvent(channel, eventCode, outOfBand, 160, 10);
	}

	/** Sets the dynamic payload |type| that should be used for telephone<br/>
	 *  events.
	 */
	public int setSendTelephoneEventPayloadType(int channel, byte type) {
		return SetSendTelephoneEventPayloadType(_p, channel, type);
	}

	/** Gets the currently set dynamic payload |type| for telephone events.
	 */
	public int getSendTelephoneEventPayloadType(int channel, ReturnValue<Byte> type) {
		OutputParam output = new OutputParam();
		int result = GetSendTelephoneEventPayloadType(_p, channel, output);
		if(result == 0) {
			type.setValue(((Integer)output.getObject()[0]).byteValue());
		}
		return result;
	}

	/** Enables or disables local tone playout for received DTMF events<br/>
	 *  out-of-band.
	 */
	public int setDtmfPlayoutStatus(int channel, boolean enable) {
		return SetDtmfPlayoutStatus(_p, channel, enable);
	}

	/** Gets the DTMF playout status.
	 */
	public int getDtmfPlayoutStatus(int channel, ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetDtmfPlayoutStatus(_p, channel, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
		}
		return result;
	}

	/** Toogles DTMF feedback state: when a DTMF tone is sent, the same tone<br/>
	 *  is played out on the speaker.
	 */
	public int setDtmfFeedbackStatus(boolean enable, boolean directFeedback) {
		return SetDtmfFeedbackStatus(_p, enable, directFeedback);
	}

	/** Toogles DTMF feedback state: when a DTMF tone is sent, the same tone<br/>
	 *  is played out on the speaker.
	 */
	public int setDtmfFeedbackStatus(boolean enable) {
		return setDtmfFeedbackStatus(enable, false);
	}

	/** Gets the DTMF feedback status.
	 */
	public int getDtmfFeedbackStatus(ReturnValue<Boolean> enabled, ReturnValue<Boolean> directFeedback) {
		OutputParam output = new OutputParam();
		int result = GetDtmfFeedbackStatus(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
			directFeedback.setValue((Boolean)output.getObject()[1]);
		}
		return result;
	}

	/** Plays a DTMF feedback tone (only locally).
	 */
	public int playDtmfTone(int eventCode, int lengthMs, int attenuationDb) {
		return PlayDtmfTone(_p, eventCode, lengthMs, attenuationDb);
	}

	/** Plays a DTMF feedback tone (only locally).
	 */
	public int playDtmfTone(int eventCode, int lengthMs) {
		return playDtmfTone(eventCode, lengthMs, 10);
	}

	/** Plays a DTMF feedback tone (only locally).
	 */
	public int playDtmfTone(int eventCode) {
		return playDtmfTone(eventCode, 200, 10);
	}

	/** Starts playing out a DTMF feedback tone locally.<br/>
	 *  The tone will be played out until the corresponding stop function<br/>
	 *  is called.
	 */
	public int startPlayingDtmfTone(int eventCode, int attenuationDb) {
		return StartPlayingDtmfTone(_p, eventCode, attenuationDb);
	}

	/** Starts playing out a DTMF feedback tone locally.<br/>
	 *  The tone will be played out until the corresponding stop function<br/>
	 *  is called.
	 */
	public int startPlayingDtmfTone(int eventCode) {
		return startPlayingDtmfTone(eventCode, 10);
	}

	/** Stops playing out a DTMF feedback tone locally.
	 */
	public int stopPlayingDtmfTone() {
		return StopPlayingDtmfTone(_p);
	}

	/** Installs an instance of a VoETelephoneEventObserver derived class and<br/>
	 *  activates detection of telephone events for the specified |channel|.
	 */
	public int registerTelephoneEventDetection(
			int channel, TelephoneEventDetectionMethods detectionMethod, VoETelephoneEventObserver observer) {
		Utility.throwNullPointerException(observer, "observer");
		return RegisterTelephoneEventDetection(_p, channel, detectionMethod.getValue(), observer);
	}

	/** Removes an instance of a VoETelephoneEventObserver derived class and<br/>
	 *  disables detection of telephone events for the specified |channel|.
	 */
	public int deRegisterTelephoneEventDetection(int channel) {
		return DeRegisterTelephoneEventDetection(_p, channel);
	}

	/** Gets the current telephone-event detection status for a specified<br/>
	 *  |channel|.
	 */
	public int getTelephoneEventDetectionStatus(int channel, ReturnValue<Boolean> enabled, 
			ReturnValue<TelephoneEventDetectionMethods> detectionMethod) {
		OutputParam output = new OutputParam();
		int result = GetTelephoneEventDetectionStatus(_p, channel, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
			detectionMethod.setValue(TelephoneEventDetectionMethods
				.fromValue((Integer) output.getObject()[1]));
		}
		return result;
	}

	protected VoEDtmf(long p) {
		_p = p;
	}

	protected long _p;

	// [end]
	
	
	
	
	
	
	
	
	
	
	
	
	
	// [start] jni api

	// Factory for the VoEDtmf sub-API. Increases an internal
	// reference counter if successful. Returns NULL if the API is not
	// supported or if construction fails.
	private static native long GetInterface(long p_voiceEngine);

	// Releases the VoEDtmf sub-API and decreases an internal
	// reference counter. Returns the new reference count. This value should
	// be zero for all sub-API:s before the VoiceEngine object can be safely
	// deleted.
	private static native int Release(long p_VoEDtmf);

	// Sends telephone events either in-band or out-of-band.
	private static native int SendTelephoneEvent(long p_VoEDtmf, int channel,
			int eventCode, boolean outOfBand, int lengthMs, int attenuationDb);

	// Sets the dynamic payload |type| that should be used for telephone
	// events.
	private static native int SetSendTelephoneEventPayloadType(long p_VoEDtmf,
			int channel, byte type);

	// Gets the currently set dynamic payload |type| for telephone events.
	private static native int GetSendTelephoneEventPayloadType(long p_VoEDtmf,
			int channel, OutputParam param);

	// Enables or disables local tone playout for received DTMF events
	// out-of-band.
	private static native int SetDtmfPlayoutStatus(long p_VoEDtmf, int channel,
			boolean enable);

	// Gets the DTMF playout status.
	private static native int GetDtmfPlayoutStatus(long p_VoEDtmf, int channel,
			OutputParam enabled);

	// Toogles DTMF feedback state: when a DTMF tone is sent, the same tone
	// is played out on the speaker.
	private static native int SetDtmfFeedbackStatus(long p_VoEDtmf,
			boolean enable, boolean directFeedback);

	// Gets the DTMF feedback status.
	private static native int GetDtmfFeedbackStatus(long p_VoEDtmf,
			OutputParam param);

	// Plays a DTMF feedback tone (only locally).
	private static native int PlayDtmfTone(long p_VoEDtmf, int eventCode,
			int lengthMs, int attenuationDb);

	// Starts playing out a DTMF feedback tone locally.
	// The tone will be played out until the corresponding stop function
	// is called.
	private static native int StartPlayingDtmfTone(long p_VoEDtmf,
			int eventCode, int attenuationDb);

	// Stops playing out a DTMF feedback tone locally.
	private static native int StopPlayingDtmfTone(long p_VoEDtmf);

	// Installs an instance of a VoETelephoneEventObserver derived class and
	// activates detection of telephone events for the specified |channel|.
	private static native int RegisterTelephoneEventDetection(long p_VoEDtmf,
			int channel, int detectionMethod, VoETelephoneEventObserver observer);

	// Removes an instance of a VoETelephoneEventObserver derived class and
	// disables detection of telephone events for the specified |channel|.
	private static native int DeRegisterTelephoneEventDetection(long p_VoEDtmf,
			int channel);

	// Gets the current telephone-event detection status for a specified
	// |channel|.
	private static native int GetTelephoneEventDetectionStatus(long p_VoEDtmf,
			int channel, OutputParam param);

	// [end]
}
